home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Snippets
/
DirectoryPopup 1.0
/
□□□DPSample Source
/
FinderObjects.c
next >
Wrap
Text File
|
1996-06-03
|
5KB
|
198 lines
/*
* Project: <none>
*
* Filename: FinderObjects.c
*
* Author: Marco Piovanelli
*
* Revision History:
*
* 1996.06.02 MP created this file
*
*/
#include "FinderObjects.h"
#include "Utilities.h"
#ifndef __ALIASES__
#include <Aliases.h>
#endif
#ifndef __APPLEEVENTS__
#include <AppleEvents.h>
#endif
#ifndef __AEREGISTRY__
#include <AERegistry.h>
#endif
#ifndef __GESTALT__
#include <Gestalt.h>
#endif
enum
{
kFinderType = 'FNDR',
kFinderSignature = 'MACS'
} ;
OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN ) ;
OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE ) ;
OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN )
{
ProcessInfoRec info ;
// start at beginning of process list
outPSN -> lowLongOfPSN = kNoProcess ;
outPSN -> highLongOfPSN = kNoProcess ;
// init process info record
BlockClear ( & info, sizeof ( info ) ) ;
info . processInfoLength = sizeof ( info ) ;
// walk the process list, looking for the given creator
while ( ( GetNextProcess ( outPSN ) == noErr ) &&
( GetProcessInformation ( outPSN, & info ) == noErr ) )
{
if ( ( info . processType == inProcessType ) && ( info . processSignature == inProcessSignature ) )
{
return noErr ;
}
}
return procNotFound ;
}
inline OSErr FinderPSN ( ProcessSerialNumber * outPSN )
{
return FindProcess ( kFinderType, kFinderSignature, outPSN ) ;
}
OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE )
{
ProcessSerialNumber finderPSN ;
AEAddressDesc finderAddress ;
OSErr err ;
InitDesc ( outAE ) ;
InitDesc ( & finderAddress ) ;
// find the process serial number of the Finder
if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
goto cleanup ;
// create an address descriptor for the target application based on the PSN
if ( ( err = AECreateDesc ( typeProcessSerialNumber, & finderPSN, sizeof ( finderPSN ), & finderAddress ) ) != noErr )
goto cleanup ;
// create the Apple event
if ( ( err = AECreateAppleEvent ( inEventClass, inEventID, & finderAddress, kAutoGenerateReturnID, kAnyTransactionID, outAE ) ) != noErr )
goto cleanup ;
// clear result code
err = noErr;
cleanup:
ForgetDesc ( & finderAddress ) ;
return err ;
}
static Boolean HasScriptableFinder ( void )
{
SInt32 response ;
return ( ( Gestalt ( gestaltFinderAttr, & response ) == noErr ) &&
( response & ( 1L << gestaltOSLCompliantFinder ) ) ) ;
}
OSErr OpenFinderObject ( const FSSpec * inThing )
{
FSSpec thing = * inThing ;
AppleEvent ae, reply ;
AEDesc thingAlias, parentAlias, thingList ;
ProcessSerialNumber finderPSN ;
OSErr err ;
InitDesc ( & ae ) ;
InitDesc ( & reply ) ;
InitDesc ( & thingAlias ) ;
InitDesc ( & parentAlias ) ;
InitDesc ( & thingList ) ;
// create a minimal alias for the specified object
if ( ( err = NewAliasMinimal ( & thing, ( AliasHandle * ) & thingAlias . dataHandle ) ) != noErr )
goto cleanup ;
thingAlias . descriptorType = typeAlias ;
if ( HasScriptableFinder ( ) )
{
// if the Finder is OSL-compliant, we can send it a
// straightforward "open" (aevt/odoc) event
if ( ( err = CreateFinderEvent ( kCoreEventClass, kAEOpen, & ae ) ) != noErr )
goto cleanup ;
// the direct parameter of the event is simply the file alias
if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & thingAlias ) ) != noErr )
goto cleanup ;
}
else
{
// older, non-OSL-compliant, Finders (from version 7.0 onward)
// require a custom "open selection" event (FNDR/sope) with much
// more complicated parameters
if ( ( err = CreateFinderEvent ( kAEFinderEvents, kAEOpenSelection, & ae ) ) != noErr )
goto cleanup ;
// create a full alias for the parent directory (enclosing folder)
// of specified object; if the object is at root level, create a full
// alias for the object itself
if ( thing . parID != fsRtParID )
{
if ( ( err = FindParentSpec ( & thing ) ) != noErr )
goto cleanup ;
}
if ( ( err = NewAlias ( nil, & thing, ( AliasHandle * ) & parentAlias . dataHandle ) ) != noErr )
goto cleanup ;
parentAlias . descriptorType = typeAlias;
// add the alias record for the parent directory to the Apple event, as direct object
if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & parentAlias ) ) != noErr )
goto cleanup ;
// create a list of descriptors for the objects to show
if ( ( err = AECreateList ( nil, 0, false, & thingList ) ) != noErr )
goto cleanup ;
if ( ( err = AEPutDesc ( & thingList, 0, & thingAlias ) ) != noErr )
goto cleanup ;
// add the object list to the Apple event, as a keySelection parameter
if ( ( err = AEPutParamDesc ( & ae, keySelection, & thingList ) ) != noErr )
goto cleanup ;
}
// bring the Finder to the foreground
if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
goto cleanup ;
if ( ( err = SetFrontProcess ( & finderPSN ) ) != noErr )
goto cleanup ;
// send the apply event
if ( ( err = AESend ( & ae, & reply, kAENoReply + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil ) ) != noErr )
goto cleanup ;
// clear result code
err = noErr ;
cleanup:
ForgetDesc ( & ae ) ;
ForgetDesc ( & reply ) ;
ForgetDesc ( & thingAlias ) ;
ForgetDesc ( & parentAlias ) ;
ForgetDesc ( & thingList ) ;
return err ;
}